using System;
using System.Drawing;

namespace Sunny.UI;

public static class Drawing
{
	public static bool GetIntersection(PointF lineFirstStar, PointF lineFirstEnd, PointF lineSecondStar, PointF lineSecondEnd, out PointF intersection)
	{
		intersection = new PointF(0f, 0f);
		float num = 0f;
		float num2 = 0f;
		int num3 = 0;
		if (lineFirstStar.X != lineFirstEnd.X)
		{
			num = (lineFirstEnd.Y - lineFirstStar.Y) / (lineFirstEnd.X - lineFirstStar.X);
			num3 |= 1;
		}
		if (lineSecondStar.X != lineSecondEnd.X)
		{
			num2 = (lineSecondEnd.Y - lineSecondStar.Y) / (lineSecondEnd.X - lineSecondStar.X);
			num3 |= 2;
		}
		switch (num3)
		{
		case 0:
			lineFirstStar.X.EqualsFloat(lineSecondStar.X);
			return false;
		case 1:
		{
			float x = lineSecondStar.X;
			float y2 = (lineFirstStar.X - x) * (0f - num) + lineFirstStar.Y;
			intersection = new PointF(x, y2);
			return true;
		}
		case 2:
		{
			float x2 = lineFirstStar.X;
			float y3 = (lineSecondStar.X - x2) * (0f - num2) + lineSecondStar.Y;
			intersection = new PointF(x2, y3);
			return true;
		}
		case 3:
		{
			if (num.EqualsFloat(num2))
			{
				return false;
			}
			float num4 = (num * lineFirstStar.X - num2 * lineSecondStar.X - lineFirstStar.Y + lineSecondStar.Y) / (num - num2);
			float y = num * num4 - num * lineFirstStar.X + lineFirstStar.Y;
			intersection = new PointF(num4, y);
			return true;
		}
		default:
			return false;
		}
	}

	public static PointF CalcAzRangePoint(this PointF center, float range, float az, float xOffset = 0f, float yOffset = 0f)
	{
		float num = (float)((double)(range * 1f) * Math.Sin((double)az * Math.PI / 180.0));
		float num2 = (float)((double)(range * 1f) * Math.Cos((double)az * Math.PI / 180.0));
		return new PointF(center.X + xOffset + num, center.Y + yOffset - num2);
	}

	public static PointF CalcAzRangePoint(this Point center, float range, float az, float xOffset = 0f, float yOffset = 0f)
	{
		float num = (float)((double)(range * 1f) * Math.Sin((double)az * Math.PI / 180.0));
		float num2 = (float)((double)(range * 1f) * Math.Cos((double)az * Math.PI / 180.0));
		return new PointF((float)center.X + xOffset + num, (float)center.Y + yOffset - num2);
	}

	public static double CalcDistance(this PointF pt1, PointF pt2)
	{
		float num = pt1.X - pt2.X;
		float num2 = pt1.Y - pt2.Y;
		return Math.Sqrt(num * num + num2 * num2);
	}

	public static double CalcDistance(this Point pt1, Point pt2)
	{
		int num = pt1.X - pt2.X;
		int num2 = pt1.Y - pt2.Y;
		return Math.Sqrt(num * num + num2 * num2);
	}

	public static double CalcAngle(this Point thisPoint, Point toPoint)
	{
		return (Math.Atan2(thisPoint.Y - toPoint.Y, thisPoint.X - toPoint.X) * 180.0 / Math.PI - 270.0 + 720.0) % 360.0;
	}

	public static double CalcAngle(this PointF thisPoint, PointF toPoint)
	{
		return (Math.Atan2(thisPoint.Y - toPoint.Y, thisPoint.X - toPoint.X) * 180.0 / Math.PI - 270.0 + 720.0) % 360.0;
	}

	public static PointF Center(this Rectangle rect)
	{
		return new PointF((float)rect.Left + (float)rect.Width / 2f, (float)rect.Top + (float)rect.Height / 2f);
	}

	public static PointF Center(this RectangleF rect)
	{
		return new PointF(rect.Left + rect.Width / 2f, rect.Top + rect.Height / 2f);
	}

	public static Color Alpha(this Color color, int alpha)
	{
		alpha = Math.Max(0, alpha);
		alpha = Math.Min(255, alpha);
		return Color.FromArgb(alpha, color);
	}

	public static bool InRect(this Point point, Rectangle rect)
	{
		if (point.X >= rect.Left && point.X <= rect.Right && point.Y >= rect.Top)
		{
			return point.Y <= rect.Bottom;
		}
		return false;
	}

	public static bool InRect(this Point point, RectangleF rect)
	{
		if ((float)point.X >= rect.Left && (float)point.X <= rect.Right && (float)point.Y >= rect.Top)
		{
			return (float)point.Y <= rect.Bottom;
		}
		return false;
	}

	public static bool InRect(this PointF point, Rectangle rect)
	{
		if (point.X >= (float)rect.Left && point.X <= (float)rect.Right && point.Y >= (float)rect.Top)
		{
			return point.Y <= (float)rect.Bottom;
		}
		return false;
	}

	public static bool InRect(this PointF point, RectangleF rect)
	{
		if (point.X >= rect.Left && point.X <= rect.Right && point.Y >= rect.Top)
		{
			return point.Y <= rect.Bottom;
		}
		return false;
	}

	public static bool IsOverlap(this Rectangle rc1, Rectangle rc2)
	{
		if (rc1.X + rc1.Width > rc2.X && rc2.X + rc2.Width > rc1.X && rc1.Y + rc1.Height > rc2.Y)
		{
			return rc2.Y + rc2.Height > rc1.Y;
		}
		return false;
	}

	public static bool IsOverlap(this RectangleF rc1, RectangleF rc2)
	{
		if (rc1.X + rc1.Width > rc2.X && rc2.X + rc2.Width > rc1.X && rc1.Y + rc1.Height > rc2.Y)
		{
			return rc2.Y + rc2.Height > rc1.Y;
		}
		return false;
	}

	public static RectangleF CreateRectangleF(this PointF pf1, PointF pf2)
	{
		return new RectangleF(Math.Min(pf1.X, pf2.X), Math.Min(pf1.Y, pf2.Y), Math.Abs(pf1.X - pf2.X), Math.Abs(pf1.Y - pf2.Y));
	}

	public static Rectangle CreateRectangle(this Point pf1, Point pf2)
	{
		return new Rectangle(Math.Min(pf1.X, pf2.X), Math.Min(pf1.Y, pf2.Y), Math.Abs(pf1.X - pf2.X), Math.Abs(pf1.Y - pf2.Y));
	}

	public static double CalcY(this PointF pf1, PointF pf2, double x)
	{
		if (pf1.Y.Equals(pf2.Y))
		{
			return pf1.Y;
		}
		if (pf1.X.Equals(pf2.X))
		{
			return double.NaN;
		}
		double num = (double)(pf2.Y - pf1.Y) * 1.0 / (double)(pf2.X - pf1.X);
		double num2 = (double)pf1.Y - num * (double)pf1.X;
		return num * x + num2;
	}

	public static double CalcX(this PointF pf1, PointF pf2, double y)
	{
		if (pf1.X.Equals(pf2.X))
		{
			return pf1.X;
		}
		if (pf1.Y.Equals(pf2.Y))
		{
			return double.NaN;
		}
		double num = (double)(pf2.Y - pf1.Y) * 1.0 / (double)(pf2.X - pf1.X);
		double num2 = (double)pf1.Y - num * (double)pf1.X;
		return (y - num2) * 1.0 / num;
	}

	public static double CalcY(this Point pf1, Point pf2, double x)
	{
		if (pf1.Y == pf2.Y)
		{
			return pf1.Y;
		}
		if (pf1.X == pf2.X)
		{
			return double.NaN;
		}
		double num = (double)(pf2.Y - pf1.Y) * 1.0 / (double)(pf2.X - pf1.X);
		double num2 = (double)pf1.Y - num * (double)pf1.X;
		return num * x + num2;
	}

	public static double CalcX(this Point pf1, Point pf2, double y)
	{
		if (pf1.Y == pf2.Y)
		{
			return pf1.X;
		}
		if (pf1.X == pf2.X)
		{
			return double.NaN;
		}
		double num = (double)(pf2.Y - pf1.Y) * 1.0 / (double)(pf2.X - pf1.X);
		double num2 = (double)pf1.Y - num * (double)pf1.X;
		return (y - num2) * 1.0 / num;
	}

	public static Color StepColor(this Color color, int alpha)
	{
		if (alpha == 100)
		{
			return color;
		}
		byte a = color.A;
		byte r = color.R;
		byte g = color.G;
		byte b = color.B;
		double num = ((double)Math.Max(alpha, 0) - 100.0) / 100.0;
		float num2;
		if (num > 100.0)
		{
			num2 = 255f;
			num = 1.0 - num;
		}
		else
		{
			num2 = 0f;
			num = 1.0 + num;
		}
		r = (byte)BlendColor((int)r, num2, num);
		g = (byte)BlendColor((int)g, num2, num);
		b = (byte)BlendColor((int)b, num2, num);
		return Color.FromArgb(a, r, g, b);
	}

	private static double BlendColor(double fg, double bg, double alpha)
	{
		double num = bg + alpha * (fg - bg);
		if (num < 0.0)
		{
			num = 0.0;
		}
		if (num > 255.0)
		{
			num = 255.0;
		}
		return num;
	}

	public static bool IsNullOrEmpty(this Color color)
	{
		if (!(color == Color.Empty))
		{
			return color == Color.Transparent;
		}
		return true;
	}

	public static bool IsValid(this Color color)
	{
		return !color.IsNullOrEmpty();
	}

	public static Point Offset(this Point point, Size size)
	{
		point.Offset(size.Width, size.Height);
		return point;
	}

	public static Size MultiplyWidth(this Size size, int multiple)
	{
		return new Size(size.Width * multiple, size.Height);
	}

	public static Size MultiplyHeight(this Size size, int multiple)
	{
		return new Size(size.Width, size.Height * multiple);
	}

	public static Size MultiplyAll(this Size size, int multiple)
	{
		return new Size(size.Width * multiple, size.Height * multiple);
	}

	public static Size MultiplyWidth(this Size size, double multiple)
	{
		return new Size((int)((double)size.Width * multiple), size.Height);
	}

	public static Size MultiplyHeight(this Size size, double multiple)
	{
		return new Size(size.Width, (int)((double)size.Height * multiple));
	}

	public static Size MultiplyAll(this Size size, double multiple)
	{
		return new Size((int)((double)size.Width * multiple), (int)((double)size.Height * multiple));
	}

	public static bool IsVisible(this Rectangle rect)
	{
		if (rect.Width > 0)
		{
			return rect.Height > 0;
		}
		return false;
	}

	public static Color RandomColor()
	{
		Random random = new Random();
		return Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256));
	}

	public static Color MixColors(this Color[] colors)
	{
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		for (int i = 0; i < colors.Length; i++)
		{
			Color color = colors[i];
			num += color.R;
			num2 += color.B;
			num3 += color.B;
		}
		return Color.FromArgb(num / colors.Length, num2 / colors.Length, num3 / colors.Length);
	}

	public static bool IsLightColor(this Color color)
	{
		return (0.299 * (double)(int)color.R + 0.587 * (double)(int)color.G + 0.114 * (double)(int)color.B) / 255.0 > 0.5;
	}

	public static Color ForeColor(Color backColor)
	{
		if (!backColor.IsLightColor())
		{
			return Color.White;
		}
		return Color.Black;
	}

	public static Size Size(this SizeF size)
	{
		return new Size(size.Width.RoundEx(), size.Height.RoundEx());
	}

	public static Point Point(this PointF point)
	{
		return new Point(point.X.RoundEx(), point.Y.RoundEx());
	}

	public static Size Add(this Size size, int width, int height)
	{
		return new Size(size.Width + width, size.Height + height);
	}

	public static SizeF Add(this SizeF size, float width, float height)
	{
		return new SizeF(size.Width + width, size.Height + height);
	}

	public static string ToHTML(this Color color)
	{
		return ColorTranslator.ToHtml(color);
	}

	public static Color ToColor(string htmlColor, int alpha = 255)
	{
		return Color.FromArgb((alpha > 255) ? 255 : alpha, ColorTranslator.FromHtml(htmlColor));
	}
}
